/********************************************************
 Name          : mac.c
 Author        : Tigran Papazyan
 Copyright     : Copyright by Antel Systems
 Description   :
 **********************************************************/
// Include Files
#include "mac.h"
#include "startup.h"
#include "cmx7164_api.h"
#include "CMX7164.h"
#include "CMX998.h"
#include "LMX2541.h"
#include "gpio.h"
#include "tc_1.h"
#include "usart_fast.h"
#include "network.h"
#include "llc/llc.h"
#include "crc8.h"
#include "crc16.h"
#include "CLI.h"
#include "board.h"
#include "pcc/pcc.h"
#include "math.h"
#include "sleep_s.h"

#define FRAME_MAX_SIZE	517

Timer_Tik MAC_tik;
Timer_Tik MAC_tik_timer;
Timer_Tik MAC_tik_998_config = 0;

Timer_Tik MAC_tik_temp_0 = 0;
Timer_Tik MAC_tik_temp_1 = 0;

unsigned char MAC_998_Initialized = 0;
unsigned int MAC_Time_slot_count = 0;

unsigned char Test_mode_data[86] =
{ 0x03, 0x14, 0x08, 0x02, 0x93, 0x02, 0x20, 0x20, 0x30, 0x31, 0x30, 0x32, 0x30,
		0x33, 0x30, 0x34, 0x30, 0x35, 0x30, 0x36, 0x30, 0x37, 0x30, 0x38, 0x30,
		0x39, 0x31, 0x30, 0x31, 0x31, 0x31, 0x32, 0x31, 0x33, 0x31, 0x34, 0x31,
		0x35, 0x31, 0x36, 0x31, 0x37, 0x31, 0x38, 0x31, 0x39, 0x32, 0x30, 0x32,
		0x31, 0x32, 0x32, 0x32, 0x33, 0x32, 0x34, 0x32, 0x35, 0x32, 0x36, 0x32,
		0x37, 0x32, 0x38, 0x32, 0x39, 0x33, 0x30, 0x33, 0x31, 0x33, 0x32, 0x33,
		0x33, 0x33, 0x34, 0x33, 0x35, 0x33, 0x36, 0x33, 0x37, 0x20, 0x20, 0x33,
		0x39 };

/*================================================================================*\
  Author      :       Khachatur Gyozalyan
 ================================================================================
 Function    :       checkCRC16
 Description :       Check the CRC16 (last 2 bytes in ptr is CRC16).
 Return      :       unsigned short - 0 - if success, 1 - if error
 Parameters  :       unsigned char *- pointer to data
 unsigned int   - length of data
 Note        :
 \*================================================================================*/
unsigned short checkCRC16(unsigned char *ptr, unsigned int len)
{
	unsigned short fact_crc16 = Crc16ByTable(ptr, len - 2); // Initial value can be 0xFFFF
	unsigned short crc16 = *(ptr + (len - 2));
	if (fact_crc16 == crc16)
		return 0;
	return 1;
}

/*================================================================================*\
  Author      :       Khachatur Gyozalyan
 ================================================================================
 Function    :       mac_input
 Description :       Process received mac frames.
 Return      :       err_t
 Parameters  :       p     - the received packet, p->payload pointing to the llc header
 Note        :
 \*================================================================================*/
err_t mac_input(unsigned char * data, unsigned int size,
		unsigned char first_block)
{
	struct MACFrameHeader * MacFrameHeader;
	struct pbuf *p;
	p = pbuf_alloc(PBUF_TRANSPORT, size, PBUF_RAM);
	memcpy(p->payload, data, size);

	/*	struct MACFrameFooter * MacFrameFooter;
	 unsigned short crc16;

	 MacFrameFooter = pbuf_footer(p, -CRC16_LENGTH);
	 crc16 = Crc16ByTable(p->payload,p->tot_len);
	 if(MacFrameFooter->crc16 != crc16)
	 return ERR_OK;*/

	if (first_block)
	{
		MacFrameHeader = p->payload;

		if (pbuf_header(p, -(s16_t) (sizeof(struct MACFrameHeader)-12)))
		{
			// Can't move over header in packet
			pbuf_free(p);
			p = NULL;
			return ERR_OK;
		}
		llc_mac_if->flag_bit.first = 1;
		_controlField = MacFrameHeader->ControlField;//aaaaaaaaaaaaaaaaaaaa
		_block_count = MacFrameHeader->BlockCount;//aaaaaaaaaaaaaaaaaaaaaaaaa
		_byte_count = MacFrameHeader->ByteCount;//aaaaaaaaaaaaaaaaaaaaaaaaaa
	}
	else
	{
		llc_mac_if->flag_bit.first = 0;
	}

	llc_netif->input(p, llc_netif);
	pbuf_free(p); //De-allocate packet buffer
	return ERR_OK;
}

/*================================================================================*\
  Author      :       Khachatur Gyozalyan
 ================================================================================
 Function    :       mac_output
 Description :       Process send mac frames.
 Return      :       err_t
 Parameters  :       q      - The pbuf(s) containing the llc packet to be sent.
 Note        :
 \*================================================================================*/
int gDatatSize = 0;
Timer_Tik TX_tik = 0;

err_t mac_output(struct pbuf *q)
{
	struct MACFrameHeader * MacFrameHeader;
	//	struct MACFrameFooter * MacFrameFooter;
	unsigned int timeslot_count;
	unsigned int block_count, byte_count;
	unsigned int Block_Size_byte = GetBlocSize(CMX7164_Modulation_Type);
	//	unsigned short crc16;

	if(mac_state == MAC_IDLE)
		return ERR_OK;

	switch (ConfigRoot.G_Network.SG_NetProtSet.param_bridging_reg.bridging_protocol)
	{
	case PROT_PCC:
		mac_transmit_data_size = pcc_create_packet(q->payload,mac_transmit_data, q->tot_len);
		TC1_delay_us(20000);
		break;
	case PROT_ANTEL:
	default :
		/* make room for MAC header - should not fail */
		if (pbuf_header(q, sizeof(struct MACFrameHeader)-12) != 0)//aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
		{
			/* bail out */
			return ERR_BUF;
		}

		MacFrameHeader = q->payload;

		timeslot_count = q->tot_len / GetTimeslotLength();
		if (q->tot_len % GetTimeslotLength())
			timeslot_count++;

		/*MacFrameHeader->MacServiceField.TDDFrameTypeIndicator = FRAME_TX_RX;
		MacFrameHeader->MacServiceField.ModulationType = GetModulationType();
		MacFrameHeader->MacServiceField.Reserved1 = 0x00;
		MacFrameHeader->MacServiceField.BlockType = GetBlocType();
		MacFrameHeader->MacServiceField.TDDFrameLength = timeslot_count;
		MacFrameHeader->MacServiceField.Reserved2 = 0x00;*/

		block_count = (q->tot_len-1) / Block_Size_byte;
		byte_count = (q->tot_len-1) % Block_Size_byte;
		if (!byte_count)
			byte_count = Block_Size_byte;
		else
			block_count++;

		MacFrameHeader->BlockCount = block_count;
		_block_count = block_count;//aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
		MacFrameHeader->ByteCount = byte_count;
		_byte_count = byte_count;//aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
		MacFrameHeader->ControlField = _controlField;//aaaaaaaaaaaaaaaaaaaaa
		//MacFrameHeader->crc16LowByte = 0;//aaaaaaaaaaaaaaaaaaaaa
		//MacFrameHeader->payload_byte_10 = MacFrameHeader->payload[10];
		MacFrameHeader->crc8 = Crc8ByTable((unsigned char*)MacFrameHeader,sizeof(struct MACFrameHeader) - sizeof(MacFrameHeader->crc8));
		//MacFrameHeader->crc16 = Crc16ByTable((unsigned char*)MacFrameHeader,sizeof(struct MACFrameHeader) - sizeof(MacFrameHeader->crc16));
		//MacFrameHeader->crc16LowByte = MacFrameHeader->crc16;//aaaaaaaaaaaaaaaaaaaaa
		//*(unsigned short*)((char*)(MacFrameHeader)+13)=  Crc16ByTable((unsigned char *)MacFrameHeader,13);
		//MacFrameHeader->crc8 = Crc8ByTable((unsigned char *) MacFrameHeader,sizeof(struct MACFrameHeader) - sizeof(MacFrameHeader->crc8));
		//MacFrameHeader->crc8 = Crc8(&(unsigned char *)MacFrameHeader,sizeof(struct MACFrameHeader) - sizeof(MacFrameHeader->crc8));
		//MacFrameHeader->crc16 = Crc16ByTable((unsigned char *)MacFrameHeader,sizeof(struct MACFrameHeader) - sizeof(MacFrameHeader->crc16));

		/*	crc16 = Crc16ByTable(q->payload,q->tot_len);
		 MacFrameFooter = pbuf_footer(q, sizeof(struct MACFrameFooter));
		 //pbuf_header(q, sizeof(struct MACFrameFooter));
		 MacFrameFooter = q->payload;
		 if(!MacFrameFooter)
		 return ERR_BUF;
		 MacFrameFooter->crc16 = crc16;*/

		//	print_pbuf(q);

		mac_transmit_data = q->payload;
		mac_transmit_data_size = q->tot_len;

		gDatatSize += mac_transmit_data_size - 6;
		//	printk("%d  %d\r\n",gDatatSize,mac_transmit_data_size - 6);
		break;
	}

	wake_if();

	CMX7164_RX_Enable(0);
	RF_Switch_Ctrl(RF_SWITCH_TX);
	CMX7164_Tx_Enable(1);
	if (mac_state != MAC_TRANSMIT)
	{
		mac_state = MAC_TRANSMIT;
		//TC1_delay_us(20000);
		MAC_tik_timer = TC1_Get_us();
		while (MAC_Done == MAC_BUSY && (int) (TC1_Get_us() - MAC_tik_timer < 500000));
		if (MAC_Done == MAC_BUSY)
			printk("error Tx Time Out");
	}
	else
		;//TC1_delay_us(5000);
	MAC_Done = MAC_BUSY;
	if ((TC1_Get_us() - TX_tik) > 30000000) // if previous to next TX enable time is greater then
		TC1_delay_us(25000); // 30s, delay 0.025s to power up preamplifier.
	TX_tik = TC1_Get_us();
	MAC_tik_timer = TC1_Get_us();
	vTaskResume(mac_task_handle);
	while (MAC_Done == MAC_BUSY && (int) (TC1_Get_us() - MAC_tik_timer< 1000000));
	return ERR_OK;
}

unsigned short check_mac_header(struct MACFrameHeader* MacFrameHeader)
//unsigned char check_mac_header(struct MACFrameHeader* MacFrameHeader)
{
	//unsigned short crc = Crc16ByTable((unsigned char *) MacFrameHeader,sizeof(struct MACFrameHeader)-sizeof(MacFrameHeader->crc16));
	unsigned char crc = Crc8ByTable((unsigned char *) MacFrameHeader,sizeof(struct MACFrameHeader)-sizeof(MacFrameHeader->crc8));
	//if (*(unsigned short*)((char*)(MacFrameHeader)+13) == crc)
	if (MacFrameHeader->crc8 == crc)
		return 0;
	return 1;
}

int frame_num = 0;
unsigned int MacHeaderError = 0;
struct MACFrameHeader TempMacFrameHeader;
unsigned char llc_header_temp = 0;
unsigned int Out_data_size = 0;
unsigned int In_data_size = 0;

unsigned int rx_packet_count = 0;
unsigned int tx_packet_count = 0;

void print_mac_header_error(void)
{
	printk("Transmit Data size = %d\r\n", Out_data_size);
	Out_data_size = 0;
	printk("Received Data size = %d\r\n", In_data_size);
	In_data_size = 0;
	printk("MAC HEADER ERRORS = %d\r\n", MacHeaderError);
	MacHeaderError = 0;
	printk("Received packet count = %d\r\n", rx_packet_count);
	rx_packet_count = 0;
	printk("Transmitted packet count = %d\r\n", tx_packet_count);
	tx_packet_count = 0;
}

void mac_task(void *pvParameters)
{
	unsigned char data_buff[1024];
	/*	char temp_dat[32] = {0x87 ,0xFF ,0xC8 ,0x7F ,0xFE ,0x87 ,0xFF ,0xE8 ,0x7F ,0xFE ,0x87 ,0xFF ,
	 0xD8, 0x40 ,0x01 ,0xA4 ,0x00 ,0x28 ,0x80 ,0x01 ,0x01 ,0xEA ,0xA8 ,0x00} ;
	 */
	struct MACFrameHeader* MacFrameHeader;
	unsigned int min_frame_size = /*sizeof(struct MACFrameHeader)*/3+ sizeof(struct LLCServiceFieldIT);
	unsigned int size;
	unsigned int last_error_received = 0;
	unsigned char last_error_led = 0;
	int i;
	//	int packet_count = 0;
	alarm_status_color = green;
	led_alarm_status_set_color(alarm_status_color);
	while (1)
	{
		switch (mac_state)
		{
			case MAC_RECEIVE:
			{
				CMX7164_RX_Enable(1);
				//			CMX7164_Tx_Enable(0);
				RF_Switch_Ctrl(RF_SWITCH_RX);
				if (mac_TX_RX_config == DEVICE_TRANSMITER)
					mac_Device_Reconfig(DEVICE_RECEIVER);

				switch (ConfigRoot.G_Network.SG_NetProtSet.param_bridging_reg.bridging_protocol)
				{
				case PROT_PCC:
					i = CMX7164_Receive_PCC_frame();
					goto MAC_DONE_PTR;
				case PROT_ANTEL:
				default:
					if (CMX7164_Modulation_Type != 4)
						i = CMX7164_Receive_MAC_Header(data_buff, UsageBlockType);
					else
						ConfigRoot.G_Network.SG_NetProtSet.param_bridging_reg.bridging_protocol = PROT_PCC ;
/*					else
					{
						//i = CMX7164_Receive_Row_Data(data_buff, ROW_DATA_FRAME_SIZE);
						i = CMX7164_Receive_PCC_frame();
						goto MAC_DONE_PTR;
					}
*/					break;
				}
				if (i == 2)
				{
					//pbuf_free(mac_pbuf); //De-allocate packet buffer
					CMX7164_IDLE();
					break;
				}
				else if (i == 1)
				{
					//	printk("Flash FIFO Error\r\n");
					vTaskSuspend(mac_task_handle);
					continue;
				}
				/*	  			if(MAC_tik%5 != 0)
				 MAC_tik -= MAC_tik%5; */

				led_state_set_color(green);
				led_state_off(PERIOD_200_MS);

				MacFrameHeader = (struct MACFrameHeader*) &data_buff;
				/*MacFrameHeader->crc16 &= 0xff00;
				MacFrameHeader->crc16 |= MacFrameHeader->crc16LowByte;
				MacFrameHeader->crc16LowByte = 0;*/
				if (check_mac_header(MacFrameHeader))
				{
					memcpy(MacFrameHeader, &TempMacFrameHeader,3); //sizeof(struct MACFrameHeader));
					data_buff[5] = llc_header_temp;
					MacHeaderError++;
					last_error_received = 0;
					last_error_led = 1;
					alarm_status_color = yellow;
					led_alarm_status_set_color(alarm_status_color);
				}
				else
				{
					if (last_error_led)
					{
						if (last_error_received > 1000)
						{
							alarm_status_color = green;
							led_alarm_status_set_color(alarm_status_color);
							last_error_led = 0;
						}
					}
					llc_header_temp = data_buff[5];
					memcpy(&TempMacFrameHeader, MacFrameHeader,3);// sizeof(struct MACFrameHeader));
				}
				if (MacFrameHeader->BlockCount > (Network_Buffer_Size + 6) / GetBlocSize(CMX7164_Modulation_Type))
					MacFrameHeader->BlockCount = (Network_Buffer_Size + 6) / GetBlocSize(CMX7164_Modulation_Type);
				if (MacFrameHeader->ByteCount > GetBlocSize(CMX7164_Modulation_Type))
					MacFrameHeader->ByteCount = GetBlocSize(CMX7164_Modulation_Type);

				if (MacFrameHeader->BlockCount == 0)
				{
					MacFrameHeader->BlockCount = 1;
					if (MacFrameHeader->ByteCount < min_frame_size)
						MacFrameHeader->ByteCount = min_frame_size;
				}
				else if (MacFrameHeader->BlockCount == 1)
				{
					if (MacFrameHeader->ByteCount < min_frame_size)
						MacFrameHeader->ByteCount = min_frame_size;
				}
				if (MacFrameHeader->ByteCount == 0)
					MacFrameHeader->ByteCount = GetBlocSize(CMX7164_Modulation_Type);

				size = (MacFrameHeader->BlockCount - 1) * GetBlocSize(CMX7164_Modulation_Type) + MacFrameHeader->ByteCount;
				In_data_size += size - 6;
				last_error_received += size - 6;
				Received_Frames_Counter++;
				if ((size > GetBlocSize(CMX7164_Modulation_Type)) && (CMX7164_Modulation_Type != 4))
				{
					mac_input(data_buff, GetBlocSize(CMX7164_Modulation_Type), 1);
					size -= GetBlocSize(CMX7164_Modulation_Type);
				}
				else
				{
					mac_input(data_buff, MacFrameHeader->ByteCount, 1);
					size -= MacFrameHeader->ByteCount;
				}
				if (CMX7164_Modulation_Type != 4)
					CMX7164_Receive_MAC_Payload(size);
MAC_DONE_PTR:
				MAC_Done = MAC_DONE;
				rx_packet_count++;
				//printk("P = %d\r\n",packet_count);
				break;
			}

			case MAC_TRANSMIT:
			{
				if (mac_TX_RX_config == DEVICE_RECEIVER)
					mac_Device_Reconfig(DEVICE_TRANSMITER);
				if (mac_transmit_data_size > 0)
				{
				/*	while(((MAC_tik%5000) > 200 ) && ((MAC_tik%5000) < 4800 ))
					MAC_tik = TC1_Get_us();
				*/
					led_state_set_color(yellow);
					led_state_off(PERIOD_200_MS);

					switch (ConfigRoot.G_Network.SG_NetProtSet.param_bridging_reg.bridging_protocol)
					{
					case PROT_PCC:
						i = CMX7164_Transmit_Row_Data(mac_transmit_data, mac_transmit_data_size);
						break;
					case PROT_ANTEL:
					default:
						if (CMX7164_Modulation_Type != 4)
							i = CMX7164_Transmit_Intermediate_bloks(mac_transmit_data, mac_transmit_data_size, UsageBlockType);
						else
							i = CMX7164_Transmit_Row_Data(mac_transmit_data, mac_transmit_data_size);
						break;
					}
					if (i)
						printk("MAC error %d", i);
					tx_packet_count++;
					Out_data_size += mac_transmit_data_size - 6;
					Sent_Frames_Counter++;
					//					printk("%d\r\n",mac_transmit_data_size);
					MAC_Done = MAC_DONE;
					MAC_tik_timer = TC1_Get_us();
					mac_transmit_data_size = 0;
					if (usart_count() == 0)
					{
						CMX7164_IDLE();
						mac_state = MAC_RECEIVE;
					}
					else
					{
						vTaskSuspend(mac_task_handle);
					}
				}
				else
				{
					if (usart_count() == 0)
					{
						CMX7164_IDLE();
						mac_state = MAC_RECEIVE;
					}
					else
						vTaskSuspend(mac_task_handle);
					//printk("erorr");
					mac_state = MAC_RECEIVE;
				}
				break;
			}

			case MAC_IDLE:
			{
				CMX7164_RX_Enable(0);
				CMX7164_Tx_Enable(0);
				RF_Switch_Ctrl(RF_SWITCH_RX);
				vTaskSuspend(mac_task_handle);
			}
			break;

			case MAC_TEST:
			{
				vTaskPrioritySet(mac_task_handle, tskIDLE_PRIORITY + 1);
				CMX998_Write(0x02, 0xFC);
				while (mac_state == MAC_TEST)
				{
					if (test_mode_param)
					{
						switch (test_mode_param)
						{
						case MAC_TEST_NONE_MOD_SIG:
							CMX7164_RX_Enable(0);
							RF_Switch_Ctrl(RF_SWITCH_TX);
							CMX7164_Tx_Enable(1);
							if (CMX7164_Preamble_Tx(1))
								printk(" ");
							switch (CMX7164_Modulation_Type)
							{
							case 1:
							case 2:
							case 3:
								CMX7164_set_Preamble_len(0x20, 0x00);
								break;
							case 4:
							case 5:
								CMX7164_set_Preamble_len(0x20, 0x00);
								break;
							case 6:
								CMX7164_set_Preamble_len(0x20, 0x00);
								break;
							default:
								CMX7164_set_Preamble_len(0x20, 0x00);
								break;
							}
							CMX7164_RAMDAC_Config(CMX7164_RAM_DAC_RAMP_UP);
							modem_mode_and_control.Word_val = 0x0082;
							CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control);
							CMX7164_RAMDAC_Config(CMX7164_RAM_DAC_RAMP_UP);
							test_mode_param = 0;
							break;
						case MAC_TEST_PRBS:
							CMX7164_RX_Enable(0);
							RF_Switch_Ctrl(RF_SWITCH_TX);
							CMX7164_Tx_Enable(1);
							if (CMX7164_Preamble_Tx(1))
								printk(" ");
							CMX7164_RAMDAC_Config(CMX7164_RAM_DAC_RAMP_UP);
							modem_mode_and_control.Word_val = 0x0032;
							CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control);
							test_mode_param = 0;
							break;
						case MAC_TEST_DEVIATION:
							CMX7164_RX_Enable(0);
							RF_Switch_Ctrl(RF_SWITCH_TX);
							CMX7164_Tx_Enable(1);
							if (CMX7164_Deviation_Tx(1))
								printk(" ");
							CMX7164_RAMDAC_Config(CMX7164_RAM_DAC_RAMP_UP);
							test_mode_param = 0;
							break;
						case MAC_TEST_PREAMBLE:
							CMX7164_RX_Enable(0);
							RF_Switch_Ctrl(RF_SWITCH_TX);
							CMX7164_Tx_Enable(1);
							if (CMX7164_Preamble_Tx(1))
								printk(" ");
							switch (CMX7164_Modulation_Type)
							{
							case 1:
							case 2:
							case 3:
								CMX7164_set_Preamble_len(0x20, 0x1E);
								break;
							case 4:
							case 5:
								CMX7164_set_Preamble_len(0x18, 0xF5);
								break;
							case 6:
								CMX7164_set_Preamble_len(0x10, 0xCC);
								break;
							default:
								CMX7164_set_Preamble_len(0x20, 0x1E);
								break;
							}
							modem_mode_and_control.Word_val = 0x0082;
							CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control);
							CMX7164_RAMDAC_Config(CMX7164_RAM_DAC_RAMP_UP);
							test_mode_param = 0;
							break;
						case MAC_TEST_NO_MOD:
							CMX7164_RX_Enable(0);
							RF_Switch_Ctrl(RF_SWITCH_TX);
							CMX7164_Tx_Enable(0);
							CMX7164_IDLE();
							CMX7164_RAMDAC_Config(CMX7164_RAM_DAC_RAMP_DOWN);
							test_mode_param = 0;
							break;
						case MAC_TEST_TRANSMIT_DATA:
							CMX7164_RX_Enable(0);
							RF_Switch_Ctrl(RF_SWITCH_TX);
							CMX7164_Tx_Enable(1);
							CMX7164_RAMDAC_Config(CMX7164_RAM_DAC_NORMAL_OPERATION);
							if (mac_TX_RX_config == DEVICE_RECEIVER)
								mac_Device_Reconfig(DEVICE_TRANSMITER);
							if (CMX7164_Modulation_Type == 4 || CMX7164_Modulation_Type == 6)
							{
								Test_mode_data[1] = 54;
								i = CMX7164_Transmit_Row_Data(Test_mode_data, 60);
							}
							else
							{
								Test_mode_data[85]++;
								Test_mode_data[85] = ((Test_mode_data[85] - '0')
										% 10) + '0';
								if (Test_mode_data[85] == '0')
								{
									Test_mode_data[84]++;
									Test_mode_data[84]
											= ((Test_mode_data[84] - '0') % 10)
													+ '0';
								}
								i = CMX7164_Transmit_Intermediate_bloks(
										Test_mode_data, 86, UsageBlockType);
								if (i)
									printk("MAC error %d", i);
							}
							if (i)
								printk("MAC error %d", i);
							break;
						}
					}
				}
				/************************************* Restore default values ***************************/
				switch (CMX7164_Modulation_Type)
				{
				case 1:
				case 2:
				case 3:
					CMX7164_set_Preamble_len(0x20, 0x1E);
					break;
				case 4:
				case 5:
					CMX7164_set_Preamble_len(0x18, 0xF5);
					break;
				case 6:
					CMX7164_set_Preamble_len(0x10, 0xCC);
					break;
				default:
					CMX7164_set_Preamble_len(0x20, 0x1E);
					break;
				}
				CMX7164_RAMDAC_Config(CMX7164_RAM_DAC_NORMAL_OPERATION);
				mac_state = MAC_TRANSMIT;
				mac_TX_RX_config = DEVICE_RECEIVER;
				vTaskPrioritySet(mac_task_handle, tskIDLE_PRIORITY + 4);
				/****************************************************************************************/
			}
			break;
		}
	}
}

void mac_task_init(void)
{
	if (CMX_nInitialized)
		mac_state = MAC_IDLE;
	else
	{
		mac_state = MAC_RECEIVE;
		//mac_state = MAC_TEST;
		//test_mode_param = MAC_TEST_NONE_MOD_SIG;
		//LMX2541_Sleep_Wake(0);
	}
	mac_TX_RX_config = DEVICE_TRANSMITER;
	xTaskCreate(mac_task, configTSK_MAC_NAME, configTSK_MAC_STACK_SIZE, NULL, configTSK_MAC_PRIORITY, &mac_task_handle);
}

int mac_Device_Reconfig(int device_state)
{
	switch (device_state)
	{
	case DEVICE_TRANSMITER:
		CMX998_Write(0x02, 0xFC);
		rx_tracking.Word_val = 0x0000;
		CMX7164_Write_WORD((CMX_WORD*) &rx_tracking);
		break;
	case DEVICE_RECEIVER:
		CMX7164_RX_Enable(1);
		CMX998_Write(0x02, 0x20);
		break;
	case DEVICE_TEST_MODE:
		CMX998_Write(0x02, 0xFC);
		break;
	}
	mac_TX_RX_config = device_state;
	return 0;
}

